class MultiPlayerSocket {
    // 构造函数，初始化WebSocket连接和游戏场地
    constructor(playground) {
        // 保存传入的游戏场地对象
        this.playground = playground;

        // 创建一个新的WebSocket连接，连接到游戏服务器
        this.ws = new WebSocket("wss://www.liuzihao.icu/wss/multiplayer/");

        // 开始监听WebSocket事件
        this.start();
    }

    // 开始监听WebSocket事件的方法
    start() {
        // 调用接收消息的方法，开始接收服务器发送的消息
        this.receive();
    }

    // 接收消息的方法
    receive() {
        // 为了在回调函数中访问MultiPlayerSocket的实例，创建一个外部引用outer
        let outer = this;
        // 当接收到服务器发送的消息时，触发此事件
        this.ws.onmessage = function (e) {
            // 解析服务器发送的JSON数据
            let data = JSON.parse(e.data);
            // 获取消息中的玩家UUID
            let uuid = data.uuid;
            // 如果消息是发送给当前玩家的，则忽略此消息
            if (uuid === outer.uuid) return false;
            // 获取消息中的事件类型
            let event = data.event;
            // 根据事件类型调用不同的处理方法
            // 如果事件类型是创建玩家，则调用相应的方法处理
            if (event === "create_player") {
                // 调用处理创建玩家的方法，传入UUID、用户名和照片
                outer.receive_create_player(uuid, data.username, data.photo);
            } else if (event === "move_to") {
                // 调用处理玩家移动的方法
                outer.receive_move_to(uuid, data.tx, data.ty);
            } else if (event === "shoot_fireball") {
                // 调用处理发射火球的方法
                outer.receive_shoot_fireball(uuid, data.tx, data.ty, data.ball_uuid);
            } else if (event === "attack") {
                // 调用处理攻击的方法
                outer.receive_attack(uuid, data.victim_uuid, data.x, data.y, data.angle, data.damage, data.ball_uuid);
            } else if (event === "flash") {
                // 调用处理闪现效果的方法
                outer.receive_flash(uuid, data.tx, data.ty);
            } else if (event === "message") {
                // 调用处理接收消息的方法
                outer.receive_message(uuid, data.username, data.text);
            }
        };
    }

    // 发送创建玩家的消息到服务器的方法
    send_create_player(username, photo) {
        // 创建一个外部引用outer以便在回调中访问MultiPlayerSocket实例
        let outer = this;
        // 发送包含事件类型、UUID、用户名和照片的JSON对象到服务器
        this.ws.send(JSON.stringify({
            'event': "create_player",
            'uuid': outer.uuid,
            'username': username,
            'photo': photo,
        }));
    }

    // 根据UUID获取玩家对象的方法
    get_player(uuid) {
        // 遍历游戏场地的玩家列表，查找与指定UUID匹配的玩家
        let players = this.playground.players;
        for (let i = 0; i < players.length; i++) {
            let player = players[i];
            if (player.uuid === uuid)
                return player;
        }
        return null;
    }

    // 处理接收到的创建玩家消息的方法
    receive_create_player(uuid, username, photo) {
        // 创建一个新的玩家对象，并设置其属性
        let player = new Player(
            this.playground, // 游戏场地
            this.playground.width / 2 / this.playground.scale, // 玩家初始X坐标
            this.playground.height * 0.5 / this.playground.scale, // 玩家初始Y坐标
            this.playground.height * 0.05 / this.playground.scale, // 玩家大小
            "white", // 玩家颜色
            this.playground.height * 0.15 / this.playground.scale, // 玩家特定属性
            "enemy", // 玩家类型
            username, // 用户名
            photo // 玩家照片
        );
        // 设置玩家的UUID
        player.uuid = uuid;
        // 将玩家添加到游戏场地的玩家列表中
        this.playground.players.push(player);
    }

    // 发送玩家移动消息到服务器的方法
    send_move_to(tx, ty) {
        let outer = this;
        // 发送包含事件类型、UUID和目标坐标的JSON对象到服务器
        this.ws.send(JSON.stringify({
            'event': "move_to",
            'uuid': outer.uuid,
            'tx': tx,
            'ty': ty,
        }));
    }

    // 处理接收到的玩家移动消息的方法
    receive_move_to(uuid, tx, ty) {
        // 根据UUID获取玩家对象，并调用其移动方法
        let player = this.get_player(uuid);
        if (player) {
            player.move_to(tx, ty);
        }
    }

    // 发送发射火球消息到服务器的方法
    send_shoot_fireball(tx, ty, ball_uuid) {
        let outer = this;
        // 发送包含事件类型、UUID、火球目标坐标和火球UUID的JSON对象到服务器
        this.ws.send(JSON.stringify({
            'event': "shoot_fireball",
            'uuid': outer.uuid,
            'tx': tx,
            'ty': ty,
            'ball_uuid': ball_uuid,
        }));
    }

    // 处理接收到的发射火球消息的方法
    receive_shoot_fireball(uuid, tx, ty, ball_uuid) {
        // 根据UUID获取玩家对象，并调用其发射火球方法
        let player = this.get_player(uuid);
        if (player) {
            let fireball = player.shoot_fireball(tx, ty);
            fireball.uuid = ball_uuid;
        }
    }

    // 发送攻击消息到服务器的方法
    send_attack(victim_uuid, x, y, angle, damage, ball_uuid) {
        let outer = this;
        // 发送包含事件类型、攻击者UUID、受害者UUID、攻击位置和属性等信息的JSON对象到服务器
        this.ws.send(JSON.stringify({
            'event': "attack",
            'uuid': outer.uuid,
            'victim_uuid': victim_uuid,
            'x': x,
            'y': y,
            'angle': angle,
            'damage': damage,
            'ball_uuid': ball_uuid,
        }));
    }

    // 处理接收到的攻击消息的方法
    receive_attack(uuid, victim_uuid, x, y, angle, damage, ball_uuid) {
        // 根据UUID获取攻击者和受害者对象，并调用受害者的接收攻击方法
        let attacker = this.get_player(uuid);
        let victim = this.get_player(victim_uuid);
        if (attacker && victim) {
            victim.receive_attack(x, y, angle, damage, ball_uuid, attacker);
        }
    }

    // 发送闪现效果消息到服务器的方法
    send_flash(tx, ty) {
        let outer = this;
        // 发送包含事件类型、UUID和闪现目标坐标的JSON对象到服务器
        this.ws.send(JSON.stringify({
            'event': "flash",
            'uuid': outer.uuid,
            'tx': tx,
            'ty': ty,
        }));
    }

    // 处理接收到的闪现效果消息的方法
    receive_flash(uuid, tx, ty) {
        // 根据UUID获取玩家对象，并调用其闪现方法
        let player = this.get_player(uuid);
        if (player) {
            player.flash(tx, ty);
        }
    }

    // 发送消息到服务器的方法
    send_message(username, text) {
        let outer = this;
        // 发送包含事件类型、UUID、用户名和消息的JSON对象到服务器
        this.ws.send(JSON.stringify({
            'event': "message",
            'uuid': outer.uuid,
            'username': username,
            'text': text,
        }));
    }

    // 处理接收到的消息的方法
    receive_message(uuid, username, text) {
        // 在游戏场地的聊天区域添加消息
        this.playground.chat_field.add_message(username, text);
    }
}